﻿using Org.BouncyCastle.Crypto.Generators;
using RBAC_Application.Dto.Input;
using RBAC_Application.Dto.Output;
using RBAC_Application.Dto.批量分配;
using RBAC_Application.Repository.Interface;
using RBAC_Model;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace RBAC_Application.Service.RBAC
{
    public class RbacService : IRbacService
    {
        private readonly IUserRepository _userRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IPermissionRepository _permissionRepository;
        private readonly ISqlSugarClient _db; // Added for UserRole and RolePermission operations

        public RbacService(
      IUserRepository userRepository,
      IRoleRepository roleRepository,
      IPermissionRepository permissionRepository,
      ISqlSugarClient db
      ) // ✅ 添加数据库依赖
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _permissionRepository = permissionRepository;
            _db = db; // ✅ 正确赋值

        }
        // 用户管理
        public UserDto GetUserById(long id)
        {
            var user = _userRepository.GetById(id);
            return user != null ? MapToUserDto(user) : null;
        }

        public List<UserDto> GetAllUsers()
        {
            var users = _userRepository.GetAll();
            return users.Select(MapToUserDto).ToList();
        }

        public List<UserDto> GetUsersByCondition(string keyword, bool? isActive)
        {
            var users = _userRepository.GetByCondition(keyword, isActive);
            return users.Select(MapToUserDto).ToList();
        }

        public void CreateUser(CreateUserInput input)
        {
            _db.Ado.BeginTran();
            try
            {
                if (_userRepository.Exists(input.UserName))
                    throw new InvalidOperationException("用户名已存在");

                var user = new User
                {
                    UserName = input.UserName,
                    RealName = input.RealName,
                    Phone = input.Phone,
                    Address = input.Address,
                    Password = HashPassword(input.Password), // ✅ 使用安全的密码加密
                    Email = input.Email,
                    IsActive = input.IsActive,
                    CreateTime = DateTime.Now
                };

                _userRepository.Add(user);
                _db.Ado.CommitTran();
            }
            catch
            {
                _db.Ado.RollbackTran();
                throw;
            }
        }

        public void UpdateUser(UpdateUserInput input)
        {
            _db.Ado.BeginTran();
            try
            {
                var user = _userRepository.GetById(input.Id);
                if (user == null)
                    throw new InvalidOperationException("用户不存在");

                user.UserName = input.UserName;
                user.Email = input.Email;
                user.IsActive = input.IsActive;
                user.RealName = input.RealName;
                user.Phone = input.Phone;
                user.Address = input.Address;

                _userRepository.Update(user);
                _db.Ado.CommitTran();
            }
            catch
            {
                _db.Ado.RollbackTran();
                throw;
            }
        }

        public void DeleteUser(long id)
        {
            _db.Ado.BeginTran();
            try
            {
                var user = _userRepository.GetById(id);
                if (user == null)
                    throw new InvalidOperationException("用户不存在");

                // ✅ 先删除用户角色关联
                _db.Deleteable<UserRole>()
                    .Where(ur => ur.UserId == id)
                    .ExecuteCommand();

                // ✅ 再删除用户
                _userRepository.DeleteUser(id);

                _db.Ado.CommitTran(); // ✅ 提交事务
            }
            catch
            {
                _db.Ado.RollbackTran(); // ✅ 回滚事务
                throw;
            }
        }

        public bool CheckUserNameExists(string userName)
        {
            return _userRepository.Exists(userName);
        }

        // 角色管理
        public RoleDto GetRoleById(long id)
        {
            var role = _roleRepository.GetById(id);
            return role != null ? MapToRoleDto(role) : null;
        }

        public List<RoleDto> GetAllRoles()
        {
            var roles = _roleRepository.GetAll();
            return roles.Select(MapToRoleDto).ToList();
        }

        public List<RoleDto> GetRolesByCondition(string keyword)
        {
            var roles = _roleRepository.GetByCondition(keyword);
            return roles.Select(MapToRoleDto).ToList();
        }

        public void CreateRole(CreateRoleInput input)
        {
            if (_roleRepository.Exists(input.RoleName))
                throw new InvalidOperationException("角色名已存在");

            var role = new Role
            {
                RoleName = input.RoleName,
                Description = input.Description,
                CreateTime = DateTime.Now
            };

            _roleRepository.Add(role);
        }

        public void UpdateRole(UpdateRoleInput input)
        {
            var role = _roleRepository.GetById(input.Id);
            if (role == null)
                throw new InvalidOperationException("角色不存在");

            role.RoleName = input.RoleName;
            role.Description = input.Description;

            _roleRepository.Update(role);
        }

        public void DeleteRole(long id)
        {
            _db.Ado.BeginTran();
            try
            {
                var role = _roleRepository.GetById(id);
                if (role == null)
                    throw new InvalidOperationException("角色不存在");

                // ✅ 先删除角色权限关联
                _db.Deleteable<RolePermission>()
                    .Where(rp => rp.RoleId == id)
                    .ExecuteCommand();

                // ✅ 再删除用户角色关联
                _db.Deleteable<UserRole>()
                    .Where(ur => ur.RoleId == id)
                    .ExecuteCommand();

                // ✅ 最后删除角色
                _roleRepository.Delete(id);

                _db.Ado.CommitTran();
            }
            catch
            {
                _db.Ado.RollbackTran();
                throw;
            }
        }

        public bool CheckRoleNameExists(string roleName)
        {
            return _roleRepository.Exists(roleName);
        }

        // 权限管理
        public PermissionDto GetPermissionById(long id)
        {
            var permission = _permissionRepository.GetById(id);
            return permission != null ? MapToPermissionDto(permission) : null;
        }

        public List<PermissionDto> GetAllPermissions()
        {
            var permissions = _permissionRepository.GetAll();
            return permissions.Select(MapToPermissionDto).ToList();
        }

        public List<PermissionDto> GetPermissionsByCondition(string keyword, string module)
        {
            var permissions = _permissionRepository.GetByCondition(keyword, module);
            return permissions.Select(MapToPermissionDto).ToList();
        }

        public void CreatePermission(CreatePermissionInput input)
        {
            if (_permissionRepository.Exists(input.PermissionName))
                throw new InvalidOperationException("权限名已存在");

            var permission = new Permission
            {
                PermissionName = input.PermissionName,
                Description = input.Description,
                Module = input.Module
            };

            _permissionRepository.Add(permission);
        }

        public void UpdatePermission(UpdatePermissionInput input)
        {
            var permission = _permissionRepository.GetById(input.Id);
            if (permission == null)
                throw new InvalidOperationException("权限不存在");

            permission.PermissionName = input.PermissionName;
            permission.Description = input.Description;
            permission.Module = input.Module;

            _permissionRepository.Update(permission);
        }

        public void DeletePermission(long id)
        {
            var permission = _permissionRepository.GetById(id);
            if (permission == null)
                throw new InvalidOperationException("权限不存在");

            _permissionRepository.Delete(id);
        }

        public bool CheckPermissionNameExists(string permissionName)
        {
            return _permissionRepository.Exists(permissionName);
        }

        // 用户角色关联
        public void AssignUserRole(AssignUserRoleInput input )
        {
            _db.Ado.BeginTran();
            try
            {
                var user = _userRepository.GetById(input.UserId);
                if (user == null)
                    throw new InvalidOperationException("用户不存在");

                var role = _roleRepository.GetById(input.RoleId);
                if (role == null)
                    throw new InvalidOperationException("角色不存在");

                // 检查是否已存在关联
                var existingUserRole = _db.Queryable<UserRole>()
                    .First(ur => ur.UserId == input.UserId && ur.RoleId == input.RoleId);

                if (existingUserRole != null)
                    throw new InvalidOperationException("用户角色关联已存在");

                var userRole = new UserRole
                {
                    UserId = input.UserId,
                    RoleId =input.RoleId
                };

                _db.Insertable(userRole).ExecuteCommand();
                _db.Ado.CommitTran(); // ✅ 提交事务
            }
            catch
            {
                _db.Ado.RollbackTran(); // ✅ 回滚事务
                throw;
            }
        }

        public void RemoveUserRole(long userId, long roleId)
        {
            _db.Deleteable<UserRole>()
                .Where(ur => ur.UserId == userId && ur.RoleId == roleId)
                .ExecuteCommand();
        }

        public List<RoleDto> GetUserRoles(long userId)
        {
            var roles = _roleRepository.GetRolesByUserId(userId);
            return roles.Select(MapToRoleDto).ToList();
        }

        // 角色权限关联
        public void AssignRolePermission(long roleId, long permissionId)
        {
            _permissionRepository.AssignRolePermission(roleId, permissionId);
        }

        public void RemoveRolePermission(long roleId, long permissionId)
        {
            _permissionRepository.RemoveRolePermission(roleId, permissionId);
        }

        public List<PermissionDto> GetRolePermissions(long roleId)
        {
            var permissions = _permissionRepository.GetRolePermissions(roleId);
            return permissions.Select(MapToPermissionDto).ToList();
        }

        // 权限校验
        public List<PermissionDto> GetUserPermissions(long userId)
        {
            var userRoles = _roleRepository.GetRolesByUserId(userId);
            var allPermissions = new List<PermissionDto>();

            foreach (var role in userRoles)
            {
                var rolePermissions = _permissionRepository.GetRolePermissions(role.Id);
                allPermissions.AddRange(rolePermissions.Select(MapToPermissionDto));
            }

            return allPermissions.Distinct().ToList();
        }

        public bool CheckUserPermission(long userId, string permissionName)
        {
            var userPermissions = GetUserPermissions(userId);
            return userPermissions.Any(p => p.PermissionName == permissionName);
        }

        public List<string> GetUserPermissionNames(long userId)
        {
            var userPermissions = GetUserPermissions(userId);
            return userPermissions.Select(p => p.PermissionName).ToList();
        }

        // 映射方法
        private UserDto MapToUserDto(User user)
        {
            return new UserDto
            {
                Id = user.Id,
                UserName = user.UserName,
                RealName = user.RealName,
                Phone = user.Phone,
                Address = user.Address,

                Email = user.Email,
                IsActive = user.IsActive,
                CreateTime = user.CreateTime
            };
        }

        private RoleDto MapToRoleDto(Role role)
        {
            return new RoleDto
            {
                Id = role.Id,
                RoleName = role.RoleName,
                Description = role.Description,
                CreateTime = role.CreateTime
            };
        }

        private PermissionDto MapToPermissionDto(Permission permission)
        {
            return new PermissionDto
            {
                Id = permission.Id,
                PermissionName = permission.PermissionName,
                Description = permission.Description,
                Module = permission.Module
            };
        }

        private string HashPassword(string password)
        {
            // ✅ 使用BCrypt加密，更安全
            return BCrypt.Net.BCrypt.HashPassword(password);
        }

        // ✅ 添加密码验证方法
        private bool VerifyPassword(string password, string hashedPassword)
        {
            return BCrypt.Net.BCrypt.Verify(password, hashedPassword);
        }

        public LoginOutput ValidateUserLogin(string userName, string password)
        {
            var user = _userRepository.GetByUserName(userName);

            if (user == null)
            {
                return new LoginOutput
                {
                    Success = false,
                    Message = "用户不存在，请进行注册"
                };
            }

            if (!user.IsActive)
            {
                return new LoginOutput
                {
                    Success = false,
                    Message = "账户未激活"
                };
            }

            if (!VerifyPassword(password, user.Password))
            {
                return new LoginOutput
                {
                    Success = false,
                    Message = "密码错误"
                };
            }

            // 获取角色列表
            var userRoles = _db.Queryable<UserRole>()
                               .Where(ur => ur.UserId == user.Id)
                               .Select(ur => ur.RoleId)
                               .ToList();
            var roles = _roleRepository.GetAll()
                                       .Where(r => userRoles.Contains(r.Id))
                                       .Select(r => r.RoleName).ToList();



            var token = "";

            return new LoginOutput
            {
                Id= user.Id,
                Success = true,
                UserName = user.UserName,
                RealName = user.RealName,
                Email = user.Email,
                Phone = user.Phone,
                Address = user.Address,
                Roles = roles,
                Token = token,
                Message = "登录成功"
            };
        }

        /// <summary>
        /// 获取角色下的用户列表
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <returns>该角色下的用户列表</returns>
        public List<UserDto> GetRoleUsers(long roleId)
        {
            // 1. 通过 UserRole 关联表查找所有属于该角色的用户ID
            var userIds = _db.Queryable<UserRole>()
                             .Where(ur => ur.RoleId == roleId)
                             .Select(ur => ur.UserId)
                             .ToList();

            if (userIds == null || userIds.Count == 0)
                return new List<UserDto>();

            // 2. 查询这些用户的详细信息
            var users = _userRepository.GetAll()
                                       .Where(u => userIds.Contains(u.Id))
                                       .ToList();

            // 3. 映射为 UserDto
            return users.Select(MapToUserDto).ToList();
        }

        /// <summary>
        /// 获取某权限下的所有角色
        /// </summary>
        /// <param name="permissionId">权限ID</param>
        /// <returns>拥有该权限的角色列表</returns>
        public List<RoleDto> GetPermissionRoles(long permissionId)
        {
            var roleIds = _db.Queryable<RolePermission>()
                             .Where(rp => rp.PermissionId == permissionId)
                             .Select(rp => rp.RoleId)
                             .ToList();

            if (roleIds == null || roleIds.Count == 0)
                return new List<RoleDto>();

            var roles = _roleRepository.GetAll()
                                       .Where(r => roleIds.Contains(r.Id))
                                       .ToList();

            return roles.Select(MapToRoleDto).ToList();
        }

        // <summary>
        /// 获取权限树结构
        /// </summary>
        /// <returns>权限树结构列表</returns>
        public List<PermissionTreeNode> GetPermissionTree()
        {
            var allPermissions = GetAllPermissions(); // 已有方法
            return allPermissions
                .GroupBy(p => p.Module)
                .Select(g => new PermissionTreeNode
                {
                    Module = g.Key,
                    Permissions = g.ToList()
                })
                .ToList();
        }
        /// <summary>
        /// 批量分配角色权限
        /// </summary>
        /// <param name="roleId">id</param>
        /// <param name="permissionIds">批量id</param>
        public void AssignRolePermissionsBatch(long roleId, List<long> permissionIds)
        {
            foreach (var permissionId in permissionIds)
            {
                AssignRolePermission(roleId, permissionId); // 已有单个分配方法
            }
        }
        /// <summary>
        /// 批量移除角色权限
        /// </summary>
        /// <param name="roleId">id</param>
        /// <param name="permissionIds">批量id</param>
        public void RemoveRolePermissionsBatch(long roleId, List<long> permissionIds)
        {
            foreach (var permissionId in permissionIds)
            {
                RemoveRolePermission(roleId, permissionId); // 已有单个移除方法
            }
        }

        /// <summary>
        /// 批量分配用户角色
        /// </summary>
        /// <param name="userId">id</param>
        /// <param name="roleIds">批量id</param>
        public void AssignUserRolesBatch(AssignUserRolesBatchInput input)
           
        {
            _db.Ado.BeginTran();
            try
            {
                // 兼容单个分配和批量分配
                var roleIds = input.RoleIds ?? new List<long>();
                if ((roleIds == null || roleIds.Count == 0) && input.RoleId > 0)
                {
                    roleIds.Add(input.RoleId);
                }

                // 查询该用户已拥有的角色，避免重复分配
                var existingRoleIds = _db.Queryable<UserRole>()
                    .Where(ur => ur.UserId == input.UserId)
                    .Select(ur => ur.RoleId)
                    .ToList();

                // 只分配未拥有的角色
                var newRoleIds = roleIds.Except(existingRoleIds).ToList();

                foreach (var roleId in newRoleIds)
                {
                    // 检查角色是否存在
                    var role = _roleRepository.GetById(roleId);
                    if (role == null)
                        throw new InvalidOperationException($"角色ID {roleId} 不存在");

                    var userRole = new UserRole
                    {
                        UserId = input.UserId,
                        RoleId = roleId
                    };
                    _db.Insertable(userRole).ExecuteCommand();
                }

                _db.Ado.CommitTran();
            }
            catch
            {
                _db.Ado.RollbackTran();
                throw;
            }
        }

        /// <summary>
        /// 批量删除用户角色
        /// </summary>
        /// <param name="userId">id</param>
        /// <param name="roleIds">批量id</param>
        public void RemoveUserRolesBatch(long userId, List<long> roleIds)
        {
            foreach (var roleId in roleIds)
            {
                RemoveUserRole(userId, roleId); // 已有单个移除方法
            }
        }
        /// <summary>
        /// 获取角色树结构
        /// </summary>
        public List<RoleTreeNode> GetRoleTree()
        {
            var allRoles = GetAllRoles();
            return allRoles.Select(r => new RoleTreeNode
            {
                Id = r.Id,
                RoleName = r.RoleName,
                Description = r.Description,
                Children = null // 或 new List<RoleTreeNode>()
            }).ToList();
        }



    }
}
